<template>
  <div class="scene-tree-wrapper" @dragenter="dragEnter($event)" @dragleave="dragLeave($event)"
    @dragover="dragOver($event)" @drop="dropFile($event)">
    <div class="scene-tree-wrapper_left" @contextmenu.stop.prevent=contexMenuEvent(undefined)></div>
    <div class="scene-tree-wrapper_center">
      <TreeComp :tree="(sceneTree as unknown as Tree<TreeItem>)" @click="whiteSpaceClick" @blur="whiteSpaceClick"
        @contextmenu.stop.prevent=contexMenuEvent(undefined)>
        <template v-slot:default="slotProps">
          <SceneTreeItemComp :sceneTreeItem="(slotProps.treeItem as unknown as SceneTreeItem)" :key="slotProps.key"
            @contexMenuEvent="(sceneUiTreeObject: SceneTreeItem | undefined) => contexMenuEvent(sceneUiTreeObject)"
            :isLastSelectedObject="(slotProps.treeItem as unknown as SceneTreeItem) === sceneTree.lastSelectedItem"
            :tree="sceneTree" :showCheckBox="false" @close="close">
          </SceneTreeItemComp>
        </template>
      </TreeComp>
      <ContextMenuCom :baseItems="menuContent"></ContextMenuCom>
    </div>
    <div class="scene-tree-wrapper_right" @contextmenu.stop.prevent=contexMenuEvent(undefined)></div>
  </div>
  <TooltipCom v-if="currentDialog == 'delete'" :content="'确定删除吗？'" :title="'删除'" :isVisible="true"
    @close="currentDialog = undefined" @confirm="deleteConfirm" />
  <DialogCom v-if="currentDialog == 'batch'" :draggable="true" title="批量旋转编辑" width="447" :visible="true"
    @close="currentDialog = undefined" @confirm="batchConfirm">
    <template v-slot:content>
      <div class="plane-box">
        <div class="plane-hpr">
          <div>
            <span>h：</span>
            <el-input-number v-model="h" controls-position="right" size="small" />
          </div>
          <div>
            <span>p：</span>
            <el-input-number v-model="p" controls-position="right" size="small" />
          </div>
          <div>
            <span>r：</span>
            <el-input-number v-model="r" controls-position="right" size="small" />
          </div>
        </div>
      </div>

    </template>
  </DialogCom>
</template>
<script setup lang="ts">
import { PropTree, SceneTree, SceneTreeItem } from "xbsj-xe2/dist-node/xe2";
import { Tree, TreeItem, TreeItemInsertFlag } from 'xbsj-xe2/dist-node/xe2-utils';
import { menuContentType } from '../../scripts/dataTypes';
import { onBeforeUnmount, ref, onMounted, computed, watch } from "vue";
import { createVueDisposer, toVR, } from "vue-xe2-plugin/dist-node/components/xe2/tools";
import { getProjectManager } from "../../scripts/getProjectManager";
import TreeComp from "./Tree.vue";
import SceneTreeItemComp from "./SceneTreeItem.vue";
import ContextMenuCom from "../common/ContextMenuCom.vue";
import TooltipCom from "../common/TooltipCom.vue";
import { ElMessage } from 'element-plus'
import DialogCom from "@/components/common/DialogCom.vue";
import { ESGeoVector } from "esobjs-xe2-plugin/dist-node/esobjs-xe2-plugin-main";
import { ESRtsFeatureEditing } from "@/scripts/esobjs/ESRtsFeatureEditing";
import { ESRtsFeatureAdding } from "@/scripts/esobjs/ESRtsFeatureAdding";

const props = withDefaults(defineProps<{
  sceneTreeWrapper: any
}>(), {});

const d = createVueDisposer(onBeforeUnmount);

const objm = getProjectManager();

const sceneTree = props.sceneTreeWrapper as SceneTree

const menuContent = ref<Array<menuContentType>>([])

const propIsShow = ref(false)

// 当前打开的弹框组件
const currentDialog = ref<undefined | string>(undefined);

const close = () => {
  propIsShow.value = false
  objm.propUiTreeManager.sceneObject = undefined;
}

const whiteSpaceClick = () => {
  sceneTree.sceneUiTree.clearAllSelectedItems()
  close()
}

//添加文件夹
const addNewTreeItem = (treeItem: SceneTreeItem | undefined, location?: TreeItemInsertFlag | undefined) => {
  const groupscenetreeitem = sceneTree.createGroupTreeItem(undefined, undefined, treeItem, location)
  if (!groupscenetreeitem) return
  groupscenetreeitem.name = '新建文件夹';
}

// 删除
const clickDelete = () => {
  currentDialog.value = 'delete'

}

// 删除确定按钮
const deleteConfirm = () => {
  const list = [...sceneTree.selectedItems] //删除选中
  list.forEach(obj => {
    if (obj.isDestroyed()) return
    obj.detachFromParent()
  })
  propIsShow.value = false
  objm.propUiTreeManager.sceneObject = undefined;
  objm.propSceneTree = undefined
  currentDialog.value = undefined
  ElMessage.success('删除成功')
}

//寻找某个文件夹上的所有的对象节点
function searchSceneObjectFromFolder(innerobjItem: SceneTreeItem, result: any[]) {
  if (innerobjItem.sceneObject) {
    result.push(innerobjItem.sceneObject)
  }
  if (innerobjItem.children) {
    for (let i = 0; i < innerobjItem.children.length; i++) {
      //@ts-ignore
      searchSceneObjectFromFolder(innerobjItem.children._innerObj[i], result);
    }
  }
}

function searchSceneObjectFromFolders(SceneTreeItem: SceneTreeItem) {
  let result: any[] = [];

  if (SceneTreeItem && SceneTreeItem.children && SceneTreeItem.children._innerObj) {
    const innerobj = SceneTreeItem.children._innerObj
    for (let index = 0; index < innerobj.length; index++) {
      //@ts-ignore
      searchSceneObjectFromFolder(innerobj[index], result);
    }
  }
  return result
}

const treeItemContexMenuEvent = (treeItem: SceneTreeItem) => {//文件夹右键
  const baseItems: Array<menuContentType> = [
    {
      text: "添加同级文件夹",
      keys: "",
      func: () => {
        addNewTreeItem(treeItem, 'After');
      },
    },
    {
      text: "添加内部文件夹",
      keys: "",
      func: () => {
        addNewTreeItem(treeItem, 'Inner');
      },
    },
    {
      text: "删除",
      keys: "",
      func: () => {
        clickDelete()
      },
    },
    {
      text: "重命名",
      keys: "",
      func: () => {
        treeItem.nameEditing = true
      },
    },
  ]
  const cimrtsItems: Array<menuContentType> = [
    {
      text: "批量旋转编辑",
      keys: "",
      func: () => {
        // 获取文件夹中所有es对象
        const folderObjs = searchSceneObjectFromFolders(treeItem)
        if (!folderObjs.length) {
          ElMessage.warning('文件夹内没有要编辑对象')
          return;
        }
        new Promise((resolve) => {
          currentDialog.value = "batch";
          const d = objm.batchRotateEvent.disposableOnce((res: string) => {
            d()
            if (res == "confirm") {

              let batchNum = 0
              let featureEditingNum = 0
              let featureAddingNum = 0
              folderObjs.map(obj => {
                batchNum++
                // 单点编辑
                if (!(obj instanceof ESGeoVector)) {
                  const rot = obj.rotation
                  obj.rotation = [rot[0] + h.value, rot[1] + p.value, rot[2] + r.value]
                  if (obj instanceof ESRtsFeatureEditing) featureEditingNum++
                  if (obj instanceof ESRtsFeatureAdding) featureAddingNum++

                }
              })
              ElMessage.success(`批量旋转编辑成功,共${batchNum}个对象,其中要素编辑${featureEditingNum}个,批量放置${featureAddingNum}个`)
              h.value = 0
              p.value = 0
              r.value = 0
            }
            currentDialog.value = undefined
            resolve("ok")
          });
        })
      },
    },
  ]
  if (sceneTree.name == "cimrtsSceneTreeWrapper") {
    baseItems.splice(baseItems.length, 0, ...cimrtsItems)
  }
  menuContent.value = baseItems
}

const h = ref(0)
const p = ref(0)
const r = ref(0)

// 批量编辑 确定按钮
const batchConfirm = () => {
  objm.batchRotateEvent.emit("confirm")
}

const whiteSpaceContexMenuEvent = () => {//空白右键
  const baseItems: Array<menuContentType> = [
    {
      text: "添加文件夹",
      keys: "",
      func: () => {
        addNewTreeItem(undefined)
      },
    },
  ];
  menuContent.value = baseItems
}

const getPropType = (sceneObject: any) => {
  let type: string = ""
  if (sceneObject.typeName == "ESRtsPolygon" || sceneObject.typeName == "ESRtsEexturedPolygon") {
    type = "waterMend"
  } else if (sceneObject.typeName == "ESRtsFeatureAdding") {
    type = "batchSet"
  } else if (sceneObject.typeName == "ESRtsFeatureEditing") {
    type = "featureEdit"
  } else if (sceneObject.typeName == "ESGeoExtrudedPolygonUFMS") {
    type = "freeDrawing"
  } else if (sceneObject.typeName == "ESGeoExtrudedPolygonUFMSFromCircle") {
    type = "circleDrawing"
  } else if (sceneObject.typeName == "ESGeoExtrudedPolygonUFMSFromLineString") {
    type = "lineDrawing"
  } else if (sceneObject.typeName == "ESOverheadLinesClippingUFMS") {
    type = "overheadLinesDrawing"
  }else if (sceneObject.typeName == "ESFeTreeAdding") {
    type = "addTree"
  }else if (sceneObject.typeName == "ESFeTreeEditing") {
    type = "editTree"
  }

  return type
}

const imageContexMenuEvent = (treeItem: SceneTreeItem) => {//节点右键

  const baseItems: Array<menuContentType> = [
    {
      text: "删除",
      keys: "",
      func: () => {
        clickDelete()
      },
    },
    {
      text: "重命名",
      keys: "",
      func: () => {
        treeItem.nameEditing = true
      },
    },
    {
      text: "编辑",
      keys: "",
      func: () => {
        // objm.propSceneTree = {
        //     propType: getPropType(treeItem.sceneObject),
        //     createOrEdit: 'edit',
        //     sceneObject: treeItem.sceneObject,
        //   }
        if (sceneTree.name == "cimrtsSceneTreeWrapper") {
          objm.propSceneTree = {
            propType: getPropType(treeItem.sceneObject),
            createOrEdit: 'edit',
            sceneObject: treeItem.sceneObject,
          }
        }
        if (sceneTree.name == "modelserSceneTreeWrapper") {
          objm.modelserPropSceneTree = {
            propType: getPropType(treeItem.sceneObject),
            createOrEdit: 'edit',
            sceneObject: treeItem.sceneObject,
          }
        }
        if (sceneTree.name == "modelser2SceneTreeWrapper") {
          objm.modelser2PropSceneTree = {
            propType: getPropType(treeItem.sceneObject),
            createOrEdit: 'edit',
            sceneObject: treeItem.sceneObject,
          }
        }
        if (sceneTree.name == "forestSceneTreeWrapper") {
          objm.forestPropSceneTree = {
            propType: getPropType(treeItem.sceneObject),
            createOrEdit: 'edit',
            sceneObject: treeItem.sceneObject,
          }
        }
        
      },
    },
  ]

  const featureEditItems: Array<menuContentType> = [
    {
      text: "属性",
      keys: "",
      func: () => {
        if (sceneTree.name == "cimrtsSceneTreeWrapper") {
          objm.propSceneTree = {
            propType: getPropType(treeItem.sceneObject),
            createOrEdit: 'property',
            sceneObject: treeItem.sceneObject,
          }
        }
      },
    },
    {
      text: "材质美化",
      keys: "",
      func: () => {
        if (sceneTree.name == "cimrtsSceneTreeWrapper") {
          objm.propSceneTree = {
            propType: getPropType(treeItem.sceneObject),
            createOrEdit: 'beautifyMaterails',
            sceneObject: treeItem.sceneObject,
          }
        }
      },
    },
  ]
  if (treeItem.sceneObject && treeItem.sceneObject.typeName == "ESRtsFeatureEditing") {
    baseItems.splice(baseItems.length, 0, ...featureEditItems)
  }


  const waterMendItems: Array<menuContentType> = [
    {
      text: "属性",
      keys: "",
      func: () => {
        if (sceneTree.name == "cimrtsSceneTreeWrapper") {
          objm.propSceneTree = {
            propType: getPropType(treeItem.sceneObject),
            createOrEdit: 'property',
            sceneObject: treeItem.sceneObject,
          }
        }
      },
    },
  ]

  if (treeItem.sceneObject && (treeItem.sceneObject.typeName == "ESRtsPolygon" || treeItem.sceneObject.typeName == "ESRtsEexturedPolygon")) {
    baseItems.splice(baseItems.length, 0, ...waterMendItems)
  }


  menuContent.value = baseItems
}

const contexMenuEvent = (treeItem: SceneTreeItem | undefined) => {//树内右键暴露出来的事件
  if (!treeItem) {
    whiteSpaceContexMenuEvent()
  } else if (treeItem.type === 'Folder') {
    treeItemContexMenuEvent(treeItem)
  } else {
    imageContexMenuEvent(treeItem)
  }
}
//拖拽Geojson
const dragEnter = (event: Event) => {
  event.preventDefault();
}
const dragLeave = (event: Event) => {
  event.preventDefault();
}
const dragOver = (event: Event) => {
  event.preventDefault();
}
const dropFile = async (event: Event) => {
  event.preventDefault();
}
</script>

<style scoped>
.scene-tree-wrapper {
  height: calc(100% - 20px);
  display: flex;
}

.scene-tree-wrapper_left,
.scene-tree-wrapper_right {
  width: 20px;
  height: 100%;
}

.scene-tree-wrapper_center {
  flex: 1;
}

.scene-tree-comp {
  width: 100%;
  height: calc(100% - 30px);
}

.plane-hpr {
  display: flex;
  gap: 10px;
}

.plane-hpr>div {
  display: flex;
  align-items: center;
}

.el-input-number--small {
  width: 100px;
}
</style>